﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.Foundation;
/*** Namespace du TextToSpeech ***/
using Windows.Phone.Speech.Synthesis;

namespace Techdays2013.Codes.TextToSpeech
{
    public class TextToSpeechHelper
    {
        /// <summary>
        /// Parler
        /// </summary>
        /// <param name="text"></param>

        public static IAsyncAction Speak(string text)
        {
            if (string.IsNullOrWhiteSpace(text) == true)
                return null;

            SpeechSynthesizer t2s = new SpeechSynthesizer();            
            return t2s.SpeakTextAsync(text);
        }

        /// <summary>
        /// Obtenir les langues des voix
        /// </summary>
        /// <returns></returns>

        public static List<CultureInfo> GetVoiceLanguages()
        {
            return InstalledVoices.All
                .Select((vi) => vi.Language)
                .Distinct()
                .Select((name) => new System.Globalization.CultureInfo(name))
                .ToList();
        }

        /// <summary>
        /// Une voix est-elle installée ?
        /// </summary>
        /// <param name="cultureInfo"></param>
        /// <returns></returns>

        public static bool VoiceInstalled(string cultureInfo)
        {
            string language = cultureInfo.ToLower();

            return GetVoiceLanguages()
                .FirstOrDefault((c) => c.Name.ToLower() == language) // Info : c.Name == "fr-FR" 
                != null;
        }

        /// <summary>
        /// Parler avec une langue et un genre spécifique
        /// </summary>
        /// <param name="text"></param>
        /// <param name="cultureInfo"></param>
        /// <param name="gender"></param>

        public static IAsyncAction Speak(string text, CultureInfo cultureInfo, VoiceGender gender)
        {
            if (cultureInfo == null)
                return null;

            return Speak(text, cultureInfo.Name, gender);
        }

        /// <summary>
        /// Parler avec une langue et un genre spécifique
        /// </summary>
        /// <param name="text"></param>
        /// <param name="cultureInfo"></param>
        /// <param name="gender"></param>

        public static IAsyncAction Speak(string text, string cultureInfo, VoiceGender gender)
        {
            if (string.IsNullOrWhiteSpace(text) == true || string.IsNullOrWhiteSpace(cultureInfo) == true)
                return null;

                SpeechSynthesizer t2s = new SpeechSynthesizer();

                string language = cultureInfo.ToLower();

                // Recherche de la voix : Langue + Genre
                var voice = InstalledVoices.All.FirstOrDefault((vi) => vi.Language.ToLower() == language && vi.Gender == gender);

                if (voice != null)
                {
                    t2s.SetVoice(voice);
                }

                return t2s.SpeakTextAsync(text);
        }

        /// <summary>
        /// Parler avec le language SSML
        /// </summary>
        /// <param name="ssml"></param>
        /// <param name="language"></param>
        /// <param name="Includeheader"></param>

        public static IAsyncAction SpeakSsml(string ssml, bool Includeheader = false, string language = null, Action<SpeechSynthesizer, SpeechBookmarkReachedEventArgs> bookmarkedReached = null)
        {
            string ssmlComplete = null;

            SpeechSynthesizer t2s = new SpeechSynthesizer();

            if (Includeheader == true)
            {
                ssmlComplete = ssml;
            }
            else
            {
                string header = "<speak version=\"1.0\" xmlns=\"http://www.w3.org/2001/10/synthesis\"";

                if (string.IsNullOrWhiteSpace(language) == true)
                {
                    language = InstalledVoices.Default.Language;
                }

                header += " xml:lang=\"" + language + "\"";
                header += ">";

                string footer = "</speak>";

                ssmlComplete = header + ssml + footer;
            }

            if (bookmarkedReached != null)
            {
                t2s.BookmarkReached +=
                (SpeechSynthesizer sender, SpeechBookmarkReachedEventArgs args) =>
                {
                    bookmarkedReached(sender, args);
                };
            }

            return t2s.SpeakSsmlAsync(ssmlComplete);
        }

        /// <summary>
        /// Bookmark
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>

        static void t2s_BookmarkReached(SpeechSynthesizer sender, SpeechBookmarkReachedEventArgs args)
        {
            throw new NotImplementedException();
        }
    }
}
